<?php

namespace App\Services;

use App\Models\Province;
use App\Models\ProvinceBatchLine;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

class ProvinceBatchSpiderService
{
    private $client;
    private $logger;
    private $proxy_enable = false;
    private $timeout = 10;
    private $maxRetries = 3;

    public function __construct(bool $proxy_enable = false)
    {
        $this->client = new Client([
            'base_uri' => 'https://static-data.gaokao.cn/www/2.0/',
            'timeout' => $this->timeout,
            'headers' => [
                'Referer' => 'https://www.gaokao.cn/',
                'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
            ]
        ]);

        // 确保logs目录存在
        $logDir = dirname(__DIR__, 2).'/storage/logs';
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755, true);
        }
        
        $this->logger = new Logger('college-spider');
        $this->logger->pushHandler(new StreamHandler($logDir.'/college-spider.log'));
        $this->proxy_enable = $proxy_enable;
    }


    /**
     * 采集省份批次数据
     */
    public function fetchProvinceDetail(Province $province): bool
    {
        return $this->withRetry(function() use ($province) {
            $url = "proprovince/{$province->gaokao_province_id}/pro.json?a=www.gaokao.cn";
            $response = $this->makeRequest($url);

            $data = json_decode($response, true);
            if ($data['code'] === '0000') {
                $this->processProvinceData($province, $data['data']);
                return true;
            }
            return false;
        }, $province);
    }

    /**
     * 处理省份数据
     * @param Province $province
     * @param array $data
     */
    public function processProvinceData(Province $province, array $data)
    {
        $processed = [];

        foreach ($data as $year => $yearData) {
            foreach ($yearData as $tType => $items) {
                foreach ($items as $item) {
                    // 数据验证
//                    if (empty($item['batch']) || empty($item['year'])) {
//                        continue;
//                    }

                    $item['t_type'] = $tType;
                    $processed[] = $this->formatItem($item);
                }
            }
        }
        ProvinceBatchLine::query()->insert($processed);
    }

    /**
     * 格式化数据项
     * @param array $item
     * @return array
     */
    public function formatItem(array $item): array
    {
        return [
            'batch' => $item['batch'] ?? null,
            'batch_name' => $item['batch_name'] ?? null,
            'convention_batch' => $item['convention_batch'] ?? null,
            'diff' => $item['diff'] ?? null,
            'major_score' => $item['major_score'] ?? null,
            'name' => $item['name'] ?? null,
            'province' => $item['province'] ?? null,
            'rank' => $item['rank'] ?? null,
            'score' => $item['score'] ?? null,
            'score_section' => $item['score_section'] ?? null,
            'type' => $item['type'] ?? null,
            'type_name' => $item['type_name'] ?? null,
            'year' => $item['year'] ?? null,
            't_type' => $item['t_type'] ?? null,
        ];
    }

    /**
     * 带重试机制的请求封装
     */
    private function withRetry(callable $callback, Province $province): bool
    {
        $attempts = 0;
        $lastError = null;

        while ($attempts < $this->maxRetries) {
            try {
                if ($callback()) {
                    return true;
                }
            } catch (\Exception $e) {
                $lastError = $e->getMessage();
                $this->logger->error("采集失败: {$lastError}", ['province_id' => $province->province_id]);
            }

            $attempts++;
            sleep(1); // 简单的延迟防止过快重试
        }

        return false;
    }

    /**
     * 发起HTTP请求
     */
    private function makeRequest(string $url): ?string
    {
        try {
            $options = [];
            $proxy_address = "http://host.docker.internal:1082";
            if ($this->proxy_enable) {
                $options['proxy'] = $proxy_address;
            }
            $response = $this->client->get($url, $options);
            return $response->getBody()->getContents();
        } catch (RequestException $e) {
            $this->logger->error("请求失败: {$e->getMessage()}", ['url' => $url]);
            throw $e;
        }
    }


    /**
     * 获取待采集的省份列表
     * @param int|null $limit
     * @return Collection
     */
    public function getProvinces(?int $limit = null): Collection
    {
        $query = Province::query()
            ->where('gaokao_province_id', '>', 0)
            ->orderBy('province_id');
            
        if ($limit) {
            $query->limit($limit);
        }

        return $query->get();
    }

    /**
     * 处理单个院校数据
     * @param Province $province 院校对象
     */
    public function processProvinceBatch(Province $province): bool
    {
        $success= $this->fetchProvinceDetail($province);
        return $success;
    }
}
